﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernate;
using NHibernate.Cfg;
using NHibernate.Linq;
using NHibernate.Tool.hbm2ddl;
using FirebirdSql.Data.FirebirdClient;
using MSH.Common.Business;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Collections;
using MSH.Common.Helpers;
using System.ComponentModel;
using System.Threading;
using System.Timers;
using Facebook;
using MSH.Common.Classes;
using MSH.Server.Classes;
using MSH.Server.Webservice;
using MSH.Server.Helpers;

namespace MSH.Server
{
    class Program
    {

        static void Main(string[] args)
        {
            
            LogHelper.LogMessage("Program.Main(): version "+ System.Reflection.Assembly.GetExecutingAssembly().GetName().Version);
            LogHelper.LogMessage("Program.Main(): MSH Server initializing");

            //Creeër nieuwe Firebird database
            //FbConnection.CreateDatabase(@"User=sysdba;Password=masterkey;Database=C:\db\MSH.FDB;Dialect=3;ServerType=0;Charset=WIN1252");
            //NHibernateHelper.SchemaExport();

            //CreateTestDataForThread(1000);

            NHibernateHelper.SchemaUpdate();

            //CreateTestData();

            /* Start webservice */

            WebServiceHost svcHost = new WebServiceHost(typeof(MSHService));

            try
            {
                svcHost.Open();

                LogHelper.LogMessage("Program.Main(): Webservice is running.");

                /* Social network providers */
                FacebookSocialNetworkProvider facebookSocialNetworkProvider = new FacebookSocialNetworkProvider();               

                Console.ReadLine();

                svcHost.Close();
            }
            catch (CommunicationException cex)
            {
                Console.WriteLine("Program.Main(): An exception occurred: {0}", cex.Message);
                svcHost.Abort();
                Console.ReadLine();
            }
    
        }

        public static void CreateTestData()
        {
            using (ISession session = NHibernateHelper.GetSessionFactory().OpenSession())
            {
     //           User u = CreateTestUser("arie");
                //u.UserSocialNetworkProfileData.Add(new UserSocialNetworkProfileData() { FieldName = "Homo", Value = "100 %",  AccountType = Common.Classes.SocialNetworkEnum.Facebook, User = u } );
           //     session.Save(u);                            

                //Users aanmaken
                User u1 = CreateTestUser("henk");
                User u2 = CreateTestUser("lars");
                User u3 = CreateTestUser("marten");
                User u4 = CreateTestUser("menno");
                User u5 = CreateTestUser("glenn");
                User u6 = CreateTestUser("nik");
                User u7 = CreateTestUser("jan");

                session.Save(u1);
                session.Save(u2);
                session.Save(u3);  
                session.Save(u4);
                session.Save(u5);
                session.Save(u6);
                session.Save(u7);

                //Vriendjes worden

                /*
                //Glenn en Menno
                UserFriend uf1 = new UserFriend() { User = u1, Friend = u2 };
                UserFriend uf2 = new UserFriend() { User = u2, Friend = u1 };

                //Glenn en Jan
                UserFriend uf3 = new UserFriend() { User = u1, Friend = u4 };
                UserFriend uf4 = new UserFriend() { User = u4, Friend = u1 };

                //Glenn en Nik
                UserFriend uf5 = new UserFriend() { User = u1, Friend = u5 };
                UserFriend uf6 = new UserFriend() { User = u5, Friend = u1 };

                //Lars en Menno
                UserFriend uf7 = new UserFriend() { User = u3, Friend = u2 };
                UserFriend uf8 = new UserFriend() { User = u2, Friend = u3 };

                //Lars en Jan
                UserFriend uf9 = new UserFriend() { User = u4, Friend = u2 };
                UserFriend uf10 = new UserFriend() { User = u2, Friend = u4 };

                //Lars en Nik
                UserFriend uf11 = new UserFriend() { User = u5, Friend = u2 };
                UserFriend uf12 = new UserFriend() { User = u2, Friend = u5 };

                session.Save(uf1);
                session.Save(uf2);
                session.Save(uf3);
                session.Save(uf4);
                session.Save(uf5);
                session.Save(uf6);
                session.Save(uf7);
                session.Save(uf8);
                session.Save(uf9);
                session.Save(uf10);
                session.Save(uf11);
                session.Save(uf12); 
                */

                using (ITransaction transaction = session.BeginTransaction())
                {
                    transaction.Commit();
                }
            }   
        }
        
        public static User CreateTestUser(String username)
        {
            User u = new User();
            u.Username = username;
            u.Password = "e358efa489f58062f10dd7316b65649e";
            u.Activated = true;
            u.ActivationRequestCount = 0;
            u.LastSeenTimestamp = u.RegisteredTimestamp = DateTime.UtcNow;
            u.UserProfile = new UserProfile() { MobilePhoneNumber = "0612345678" };
            u.UserSettings = new UserSettings() { LocationPrivacy = PrivacyEnum.Friends, ProfilePrivacy = PrivacyEnum.Friends };
            return u;

        }

        public static void CreateTestDataForThread(int userCount)
        {
            PrivacyEnum profilePrivacy = PrivacyEnum.Public;
            PrivacyEnum locationPrivacy = PrivacyEnum.Private;
            for (int i = 1; i <= userCount; i++)
            {
                if (i % 2 == 0)
                {
                    if (profilePrivacy == PrivacyEnum.Public)
                        profilePrivacy = PrivacyEnum.Friends;
                    else if (profilePrivacy == PrivacyEnum.Friends)
                        profilePrivacy = PrivacyEnum.Private;
                    else if (profilePrivacy == PrivacyEnum.Private)
                        profilePrivacy = PrivacyEnum.Public;
                }
                if (i % 3 == 0)
                {
                    if (locationPrivacy == PrivacyEnum.Public)
                        locationPrivacy = PrivacyEnum.Friends;
                    else if (locationPrivacy == PrivacyEnum.Friends)
                        locationPrivacy = PrivacyEnum.Private;
                    else if (locationPrivacy == PrivacyEnum.Private)
                        locationPrivacy = PrivacyEnum.Public;
                }
                CreateTestUserForThread("Thread" + i, locationPrivacy, profilePrivacy);
            }

            CreateRandomFriends();

        }

        public static void CreateTestUserForThread(String username, PrivacyEnum location, PrivacyEnum profile)
        {
            User u = new User();
            u.Username = username;
            u.Password = "e358efa489f58062f10dd7316b65649e";
            u.Activated = true;
            u.ActivationRequestCount = 0;
            u.LastSeenTimestamp = u.RegisteredTimestamp = DateTime.UtcNow;
            u.UserProfile = new UserProfile() { MobilePhoneNumber = "0612345678" };
            u.UserSettings = new UserSettings() { LocationPrivacy = location, ProfilePrivacy = profile};

            ISession session = NHibernateHelper.GetSessionFactory().OpenSession();

            using (ITransaction trans = session.BeginTransaction())
            {
                session.Save(u);
                trans.Commit();
            }
        }

        public static void CreateRandomFriends()
        {
            ISession session = NHibernateHelper.GetSessionFactory().OpenSession();
            
            IList<User> users = session.Query<User>().ToList<User>();
            Random rd = new Random();
            

            foreach (User us in users)
            {
                for (int i = 0; i < users.Count / 20; i++)
                {
                    int nr = rd.Next(users.Count - 1);
                    if(nr == us.ID)
                        nr++;

                    bool blocked = false;
                    bool friendBlocked = false;
                    if (i % 7 == 0)
                        blocked = true;
                    if (i % 12 == 0)
                        friendBlocked = true;

                    if (i % 9 == 0)
                    {
                        int count = session.Query<UserFriend>().Where(u => u.User == us && u.Friend == users[nr]).Count();
                        if (count == 0)
                        {
                            us.UserFriends.Add(new UserFriend() { Blocked = false, User = us, Friend = users[nr] });
                            session.Save(us);
                        }
                    }
                    else
                    {
                        int count = session.Query<UserFriend>().Where(u => u.User == us && u.Friend == users[nr]).Count();
                        int count2 = session.Query<UserFriend>().Where(u => u.User == users[nr] && u.Friend == us).Count();
                        if (count == 0 && count2 == 0)
                        {
                            us.UserFriends.Add(new UserFriend() { Blocked = blocked, User = us, Friend = users[nr] });
                            users[nr].UserFriends.Add(new UserFriend() { Blocked = friendBlocked, User = users[nr], Friend = us });
                            session.Save(users[nr]);
                            session.Save(us);
                        }
                    }
                }
                using (ITransaction trans = session.BeginTransaction())
                {                  
                    trans.Commit();
                }


            }

            


        }
    }
}
